/*
 * @(#)XfdmsystemStyleDialog.java        1.0 2000/05/09
 *
 * This file is part of Xfuzzy 3.0, a design environment for fuzzy logic
 * based systems.
 *
 * (c) 2000 IMSE-CNM. The authors may be contacted by the email address:
 *                    xfuzzy-team@imse.cnm.es
 *
 * Xfuzzy is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Xfuzzy is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
//VENTANA DE CONFIGURACION DEL ESTILO DE SISTEMA	//
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

package xfuzzy.xfdm.view;

import xfuzzy.util.*;
import xfuzzy.xfdm.model.*;
import xfuzzy.xfdm.view.listener.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

public class XfdmSystemStyleDialog extends JDialog implements IXfdmFrame {

	/**
	 * C�digo asociado a la clase serializable
	 */
	private static final long serialVersionUID = 95505666603018L;

	//----------------------------------------------------------------------------//
	//                            MIEMBROS PRIVADOS                               //
	//----------------------------------------------------------------------------//

	/**
	 * Ventana principal de la herramienta
	 */
	private Xfdm xfdm;
	
	/**
	 * Configuraci�n del proceso de extracci�n de conocimiento
	 */
	private XfdmConfig config;
	
	/**
	 * Campo para introducir el nombre de la base de conocimiento
	 */
	private XTextField name;
		
	/**
	 * Lista de botones de selecci�n del tipo de salida
	 */
	private JToggleButton toggle[];
	
	/**
	 * Botones de selecci�n del operador de conjunci�n
	 */
	private JRadioButton operator[];
	
	/**
	 * Bot�n de selecci�n de la opci�n de creaci�n de la estructura
	 */
	private JRadioButton creation;
	
	/**
	 * Objeto en edici�n
	 */
	private XfdmSystemStyle editing;

	//----------------------------------------------------------------------------//
	//                               CONSTRUCTOR                                  //
	//----------------------------------------------------------------------------//

	/**
	 * Constructor
	 */
	public XfdmSystemStyleDialog(Xfdm xfdm){
		super(xfdm,"Xfdm",true);
		this.xfdm = xfdm;
		this.config = xfdm.getConfig();
		this.editing = new XfdmSystemStyle(this.config.getSystemStyle());
		build();
		setStyle();
	}

	//----------------------------------------------------------------------------//
	//                             M�TODOS P�BLICOS                               //
	//----------------------------------------------------------------------------//

	/**
	 * Acci�n de cerrar la ventana
	 */
	public void close() {
		setVisible(false);
	}
	
	/**
	 * Acci�n de almacenar los datos y cerrar la ventana
	 */
	public void actionSet() {
		try { getStyle(); } catch(Exception ex) { return; }
		config.setSystemStyle(new XfdmSystemStyle(editing));
		xfdm.refresh();
		setVisible(false); 
	}

	/**
	 *  Acci�n de cerrar la ventana
	 */
	public void actionCancel() {
		setVisible(false); 
	}

	//----------------------------------------------------------------------------//
	//                             M�TODOS PRIVADOS                               //
	//----------------------------------------------------------------------------//

	/**
	 * Generaci�n de la ventana
	 */
	private void build() {
		ActionListener actionListener = new XfdmSystemActionListener(this);
		ChangeListener changeListener = new XfdmSystemChangeListener(this);
		
		String lb[] = {"Set", "Cancel"};
		XCommandForm form = new XCommandForm(lb,lb,actionListener);
		form.setCommandWidth(150);
		form.block();

		toggle = new JToggleButton[4];
		JPanel stbox = new JPanel();
		stbox.setLayout(new GridLayout(2,2));
		ButtonGroup stbg = new ButtonGroup();
		ImageIcon icon[] = {
				XfdmIcons.singleton,  XfdmIcons.bell,
				XfdmIcons.takagi,  XfdmIcons.singletons };

		String togglelabel[] = {
				"Fuzzy Mean", " Weighted Fuzzy Mean ",
				"Takagi-Sugeno", "Classification" };

		for(int i=0; i<toggle.length; i++) {
			toggle[i] = new JToggleButton(togglelabel[i],icon[i]);
			toggle[i].setFont(XConstants.textfont);
			toggle[i].setVerticalTextPosition(JToggleButton.BOTTOM);
			toggle[i].setHorizontalTextPosition(JToggleButton.CENTER);
			toggle[i].setOpaque(true);
			toggle[i].setBorder(BorderFactory.createRaisedBevelBorder());
			toggle[i].setFocusPainted(false);
			toggle[i].setContentAreaFilled(false);
			toggle[i].addChangeListener(changeListener);
			stbg.add(toggle[i]);
			stbox.add(toggle[i]);
		}

		name = new XTextField("");

		operator = new JRadioButton[2];
		operator[0] = new JRadioButton("min");
		operator[1] = new JRadioButton("prod");

		Box opanel = new Box(BoxLayout.X_AXIS);
		opanel.add(Box.createHorizontalStrut(10));
		opanel.add(operator[0]);
		opanel.add(operator[1]);

		ButtonGroup rbg = new ButtonGroup();
		rbg.add(operator[0]);
		rbg.add(operator[1]);

		creation = new JRadioButton("Generate");
		Box cpanel = new Box(BoxLayout.X_AXIS);
		cpanel.add(Box.createHorizontalStrut(10));
		cpanel.add(creation);

		JPanel lpanel = new JPanel();
		lpanel.setLayout(new GridLayout(4,2));
		lpanel.add(new XLabel("Rule base name"));
		lpanel.add(name);
		lpanel.add(new XLabel("Conjunction operator"));
		lpanel.add(opanel);
		lpanel.add(new XLabel("System structure"));
		lpanel.add(cpanel);

		Box lbox = new Box(BoxLayout.Y_AXIS);
		lbox.add(lpanel);
		lbox.add(Box.createVerticalGlue());

		Box box = new Box(BoxLayout.X_AXIS);
		box.add(Box.createHorizontalStrut(5));
		box.add(lbox);
		box.add(Box.createHorizontalStrut(5));
		box.add(stbox);
		box.add(Box.createHorizontalStrut(5));

		Container content = getContentPane();
		content.setLayout(new BoxLayout(content,BoxLayout.Y_AXIS));
		content.add(new XLabel("System Style"));
		content.add(Box.createVerticalStrut(5));
		content.add(box);
		content.add(Box.createVerticalStrut(5));
		content.add(form);

		setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
		addWindowListener(new XfdmWindowListener(this));
		pack();
		setLocation();
	}

	/**
	 * Coloca la ventana en la pantalla	
	 */
	private void setLocation() {
		Dimension frame = getSize();
		Dimension screen = getToolkit().getScreenSize();
		setLocation((screen.width - frame.width)/2,(screen.height - frame.height)/2);
	}

	/**
	 * Actualiza los datos de estilo del sistema
	 */
	private void setStyle() {
		name.setText(editing.getKnowledgeBase());
		toggle[editing.getDefuzMethod()].setSelected(true);
		operator[editing.getAndOperator()].setSelected(true);
		creation.setSelected(editing.createSystem());
		setConstraints();
	}

	/**
	 * Considera las restricciones que imponen los algoritmos
	 */
	private void setConstraints() {
		XfdmAlgorithm algorithm = config.getAlgorithm();
		if(algorithm == null) return;
		if(algorithm.supportsClassification() && !algorithm.supportsRegression()) {
			editing.setDefuzMethod(XfdmSystemStyle.CLASSIFICATION);
			toggle[XfdmSystemStyle.CLASSIFICATION].setSelected(true);
			for(int i=0; i<3; i++) toggle[i].setEnabled(false);
		}
		if(!algorithm.supportsClassification() && algorithm.supportsRegression()) {
			if(editing.getDefuzMethod() == XfdmSystemStyle.CLASSIFICATION) {
				editing.setDefuzMethod(XfdmSystemStyle.FUZZYMEAN);
				toggle[XfdmSystemStyle.CLASSIFICATION].setSelected(false);
				toggle[XfdmSystemStyle.FUZZYMEAN].setSelected(true);
			}
			toggle[XfdmSystemStyle.CLASSIFICATION].setEnabled(false);			
		}
		if(algorithm.needSystemStructure()) {
			editing.setCreationCondition(true);
			creation.setSelected(editing.createSystem());
			creation.setEnabled(false);			
		}		
	}

	/**
	 * Actualiza la variable seleccionada con los datos de estilo
	 */
	private void getStyle() throws Exception {
		String rbname = getIdentifier(name);
		if(rbname == null) throw new Exception();
		editing.setKnowledgeBase(rbname);
		if(operator[0].isSelected()) editing.setAndOperator(XfdmSystemStyle.MIN);
		else editing.setAndOperator(XfdmSystemStyle.PROD);
		for(int i=0;i<toggle.length;i++) if(toggle[i].isSelected()) editing.setDefuzMethod(i);
		editing.setCreationCondition(creation.isSelected());
	}

	/**
	 * Detecta posibles errores en el nombre de la base de reglas
	 */
	private String getIdentifier(XTextField field) {
		String id = field.getText().trim();
		if(!XConstants.isIdentifier(id)) {
			field.setText("");
			XDialog.showMessage(field,"Not a valid identifier");
			return null;
		}
		return id;
	}

}


